package com.banmao.youZone.job;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.http.HttpResponse;
import com.banmao.youZone.consts.CommonConst;
import com.banmao.youZone.entity.RequestProperty;
import com.banmao.youZone.entity.TaskTrigger;
import com.banmao.youZone.entity.UserVO;
import com.banmao.youZone.mapper.RequestPropertyMapper;
import com.banmao.youZone.mapper.UserMapper;
import com.banmao.youZone.util.ClockInUtil;
import com.banmao.youZone.util.EMailUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.*;

@Slf4j
@Component
public class ExecuteClockJob {

    private static final List<TaskTrigger> taskList = Collections.synchronizedList(new LinkedList<>());

    @Resource
    private RequestPropertyMapper requestPropertyMapper;

    @Resource
    private UserMapper userMapper;

    @Value("${mail.defaultReceivers:''}")
    private String defaultReceivers;

    public static void addTask(TaskTrigger trigger) {
        taskList.add(trigger);
    }

    @Scheduled(initialDelay = 5000, fixedRate = 10000)
    private void excute() {
//        log.info("[ExecuteClockJob]started...");

        DateTime now = DateTime.now();

        Iterator<TaskTrigger> iterator = taskList.iterator();
        if (iterator.hasNext()) {
            log.info("[ExecuteClockJob]started...");
        }
        while (iterator.hasNext()) {
            TaskTrigger next = iterator.next();
            DateTime predictExecuteTime = next.getPredictExecuteTime();
            if (predictExecuteTime != null && predictExecuteTime.compareTo(now) < 0) {
                iterator.remove();
                if (predictExecuteTime.between(now, DateUnit.MINUTE) > 30) {
                    continue;
                }
                log.info("[ExecuteClockJob]开始执行,triggerId:{}", next.getId());

                Thread.startVirtualThread(() -> {
                    log.info("[VirtualThread]启动,triggerId:{}", next.getId());
                    RequestProperty requestProperty = requestPropertyMapper.selectById(next.getUserId());

                    UserVO userVO = userMapper.selectById(next.getUserId());
                    if (userVO == null) {
                        throw new RuntimeException("未查询到用户用户:" + next.getUserId());
                    }

                    String emails = String.join(",", new ArrayList<String>() {{
                        if (StringUtils.isNotBlank(defaultReceivers)) {
                            add(defaultReceivers);
                        }
                        if (StringUtils.isNotBlank(userVO.getMail())) {
                            add(userVO.getMail());
                        }
                    }});

                    String jobType = "日常";
                    if (next.getPrecisionDateTime() != null) {
                        jobType = "单次";
                    }

                    CommonConst.USER_THREAD_LOCAL.set(userVO);

                    try (HttpResponse response = ClockInUtil.clock(requestProperty)) {
                        if (response.getStatus() == 200) {
                            log.info("[{}]打卡成功", userVO.getUserId());
                        } else {
                            log.error("[{}]打卡失败", userVO.getUserId());
                            throw new RuntimeException(response.body());
                        }

                        log.info("[VirtualThread]执行完成,triggerId:{},结果:{}", next.getId(), response.body());

                        String emailTitle = (userVO == null ? "UNKOWN" : userVO.getUsername())
                                + "的" + jobType + "定时任务已执行";
                        if (StringUtils.isNotBlank(next.getEmailTitle())) {
                            emailTitle = next.getEmailTitle();
                        }
                        String emailContent = "执行成功";
                        if (StringUtils.isNotBlank(next.getEmailContent())) {
                            emailContent = next.getEmailContent();
                        }

                        EMailUtil.sendEmail(emails, emailTitle, emailContent);

                    } catch (Exception e) {
                        log.error("[VirtualThread]执行失败,msg:{},error:", e.getMessage(), e);
                        EMailUtil.sendEmail(emails, (userVO == null ? "UNKOWN" : userVO.getUsername())
                                + "的" + jobType + "定时任务执行失败", e.getMessage());
                    } finally {
                        CommonConst.USER_THREAD_LOCAL.remove();
                    }
                });
            }

        }

    }

}
